 /*
  * Contributor(s): Yuan An yuan.an@ischool.drexel.edu
 */
package main.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import y.base.Edge;
import y.base.Node;

/**representation of a path in the ontology graph.
 * @author Yuan An
 */
public class OntoPath implements OntoEle, Serializable{
	
	private ArrayList<OntoEle> path; //this holds the Entity, Relationship, and Attributes
	
	private ArrayList<Edge> edgePath; //this holds the edges of the path
	
	
	public OntoPath(){
		
		path=new ArrayList<OntoEle>();
		
		edgePath = new ArrayList<Edge>();
		
	}
	
	
	/*************************
	 * Here goes the operations on the edgePath
	********************/
	
	public void addEdge(Edge e){
		edgePath.add(e);
	}
	
	public void addAllEdges(OntoPath other){
		edgePath.addAll(other.getEdgePath());
	}
	
	public ArrayList<Edge> getEdgePath(){
		return edgePath;
	}
	
	public int getEdgePathLength(){
		return edgePath.size();
	}
	
	//get the first node in the path
	public Node getFirstNode(){
		if(edgePath.isEmpty())
			return null;
		else{ 
			Edge firstEdge = edgePath.get(0);
			return firstEdge.source();
		}
	}
	
	//get the last node in the path
	public Node getLastNode(){
		if(edgePath.isEmpty())
			return null;
		
		else{
			Edge lastEdge = edgePath.get(edgePath.size() - 1);
			return lastEdge.target();
		}
	}
	
	public boolean isSameEdgePath(OntoPath p){
		
		boolean ans=true;
		
		if(getEdgePathLength()!=p.getEdgePathLength())
			return false;
		
		ArrayList<Edge> pEdgePath=p.getEdgePath();
		
		for(int i=0;i<pEdgePath.size();i++){
			
			Edge pEdge = pEdgePath.get(i);
			Edge edge = edgePath.get(i);
			
			if(pEdge != edge){
				ans=false;
				break;
			}
		}
		
		return ans;	
	}
	
	//check whether this path contains all edges of the given edgePath
	public boolean containsEdgePath(OntoPath aPath){
		boolean ans=true;
		
		ArrayList<Edge> edges = aPath.getEdgePath();
		
		for(int i=0;i<edges.size();i++){
			
			if(!edgePath.contains(edges.get(i))){
				ans=false;
				break;
			}
		}
		
		return ans;	
	}
	
	//Here goes the operations on the path containing a list of ontology elements
	public void addPathNode(OntoEle n){
		path.add(n);
	}
	
	public void addAll(OntoPath other){
		path.addAll(other.getPath());
	}
	

	public ArrayList<OntoEle> getPath(){
		return path;
	}
	
	public int getLength(){
		return path.size() - 1;
	}
	
	public OntoEle getFirst(){
		
		if(path.isEmpty())
			return null;
		
		return path.get(0);
	}
	
	public OntoEle getLast(){
		if(path.isEmpty())
			return null;
		
		return path.get(path.size() - 1);
	}
	
	public boolean isSamePath(OntoPath p){
		boolean ans=true;
		
		if(getLength()!=p.getLength())
			return false;
		
		ArrayList<OntoEle> pPath=p.getPath();
		
		for(int i=0;i<pPath.size();i++){
			
			OntoEle pNode = pPath.get(i);
			OntoEle node = path.get(i);
			
			if(pNode != node){
				ans=false;
				break;
			}
		}
		
		return ans;	
	}
	
	//check whether this path contains all OntoEles of the given path
	public boolean contains(OntoPath aPath){
		boolean ans=true;
		
		ArrayList<OntoEle> nodes=aPath.getPath();
		
		for(int i=0;i<nodes.size();i++){
			
			if(!path.contains(nodes.get(i))){
				ans=false;
				break;
			}
		}
		
		return ans;	
	}
	
	
	public String display(){
		
		String ans="";
		
		for(int i=0;i<path.size();i++){
		
			OntoEle n = path.get(i);
			
			String name = n.getName();
			
			if(n instanceof Attribute || n instanceof Relationship)
				name = "<" + name + ">";
			else
				name = "[" + name + "]";
			
			if(i == path.size() - 1)
				ans += name;
			else
				ans += name + "-";
		}
		
		
		return ans;
	}
	
	public String displayEdgePath(){
		String ans = "";
		
		for(int i = 0; i < edgePath.size(); i++){
			
			Edge edge = edgePath.get(i);
			
			if(i != edgePath.size() - 1)
				ans += edge.toString() + "|";
			else
				ans += edge.toString();
			
		}
		
		return ans;
	}
	
	/*
	public String toString(){
		
		String ans="";
		
		for(int i=0;i<path.size();i++){
		
			OntoEle n = path.get(i);
			
			String name = n.getName();
			
			if(n instanceof Attribute || n instanceof Relationship)
				name = "<" + name + ">";
			else
				name = "[" + name + "]";
			
			if(i == path.size() - 1)
				ans += name;
			else
				ans += name + "-";
		}
		
		return ans;
	}
	*/

	@Override
	public String getName() {
		// TODO Auto-generated method stub
		return toString();
	}
}
